package com.mmzssblog.wordcloud;

import com.kennycason.kumo.CollisionMode;
import com.kennycason.kumo.WordCloud;
import com.kennycason.kumo.WordFrequency;
import com.kennycason.kumo.bg.CircleBackground;
import com.kennycason.kumo.bg.PixelBoundaryBackground;
import com.kennycason.kumo.font.KumoFont;
import com.kennycason.kumo.font.scale.SqrtFontScalar;
import com.kennycason.kumo.image.AngleGenerator;
import com.kennycason.kumo.nlp.FrequencyAnalyzer;
import com.kennycason.kumo.nlp.FrequencyFileLoader;
import com.kennycason.kumo.nlp.tokenizers.ChineseWordTokenizer;
import com.kennycason.kumo.palette.ColorPalette;

import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author ：mmzsblog.cn
 * @date ：Created in 2021/11/30 13:51
 * @description：通过读取数组生成词云
 * @modified By：
 * @version:
 */
public class CreateWordCloudByArrayService {

    // 照片纵横比
    private double ratio = 1;

    // 获取词云图片
    // pngOutputPath：图片输出路径，应该以.png结尾
    public void generate(String pngOutputPath) throws IOException {
        final FrequencyAnalyzer frequencyAnalyzer = new FrequencyAnalyzer();
        // 共检索多少个词
        frequencyAnalyzer.setWordFrequenciesToReturn(1000);
        // 单词最短长度，一个汉字和一个英文字符都是1
        frequencyAnalyzer.setMinWordLength(2);
//        frequencyAnalyzer.setStopWords(loadStopWords());
        // 设置中文支持，另一种加载方式不用设置
        frequencyAnalyzer.setWordTokenizer(new ChineseWordTokenizer());

        final List<WordFrequency> wordFrequencies = new ArrayList<>();
        // 加载词云有两种方式，一种是在txt文件中统计词出现的个数，另一种是直接给出每个词出现的次数，这里使用第二种
        // 这里用后端技术书籍来随机生成词云
        String[] books = {"Spring实战", "Spring源码深度解析", "SpringBoot实战",
                "SpringBoot2精髓", "一步一步学SpringBoot2", "Spring微服务实战",
                "Head First Java", "Java并发编程实战", "深入理解Java 虚拟机",
                "Head First Design", "effective java", "J2EE development without EJB",
                "TCP/IP卷一", " 计算机网络：自顶向下", "图解HTTP和图解TCP/IP",
                "计算机网络", "深入理解计算机系统", "现代操作系统",
                "Linux内核设计与实现", "Unix网络编程", "数据结构与算法",
                "算法导论", "数据结构与算法（Java版）", "算法图解，啊哈算法",
                "剑指offer", "LeetCode", " Java编程思想", "Java学习之道",
                "Java核心技术卷一", "深入理解JVM虚拟机", "Java并发编程实战",
                " Java并发编程艺术", "Java性能调优指南", "Netty权威指南",
                "深入JavaWeb技术内幕", "How Tomcat Works", "Tomcat架构解析",
                "Spring实战", "Spring源码深度解析", "Spring MVC学习指南",
                "Maven实战", "sql必知必会", "深入浅出MySQL", "架构师的自我修炼",
                "Spring cloud微服务实战", "SpringBoot与Docker微服务实战", "深入理解SpringBoot与微服务架构"
        };
        // 加入分词并随机生成权重，每次生成得图片都不一样
        for (String book : books) {
            wordFrequencies.add(new WordFrequency(book, new Random().nextInt(books.length)+1));
        }

        // 生成图片的像素大小
        final Dimension dimension = new Dimension(500, (int) (500 * ratio));
        final WordCloud wordCloud = new WordCloud(dimension, CollisionMode.PIXEL_PERFECT);
        // 调节词云的稀疏程度，越高越稀疏
        wordCloud.setPadding(10);

        // 设置背景色
        wordCloud.setBackgroundColor(new Color(255, 255, 255));
        // 设置背景图片
        // shapePicPath：词云形状图片路径，其背景应为透明背景，格式为png
//        wordCloud.setBackground(new PixelBoundaryBackground(shapePicPath));
        // 因为我这边是生成一个圆形,这边设置圆的半径
        wordCloud.setBackground(new CircleBackground(255));

        // 颜色模板，不同频率的颜色会不同
        wordCloud.setColorPalette(new ColorPalette(new Color(0x4055F1), new Color(0x408DF1), new Color(0x40AAF1), new Color(0x40C5F1), new Color(0x40D3F1), new Color(0xFFFFFF)));
        // 设置字体：此处不设置会出现中文乱码
        Font font = new java.awt.Font("STSong-Light", 2, 18);

        wordCloud.setKumoFont(new KumoFont(font));
        // 设置偏转角，角度为0时，字体都是水平的
//        wordCloud.setAngleGenerator(new AngleGenerator(0, 90, 9));
        wordCloud.setAngleGenerator(new AngleGenerator(0));
        // 字体的大小范围，最小是多少，最大是多少
        wordCloud.setFontScalar(new SqrtFontScalar(5, 40));
        wordCloud.build(wordFrequencies);
        wordCloud.writeToFile(pngOutputPath);
    }
}

